package service

import (
	"context"
	"fmt"

	"go.uber.org/zap"

	"yanxue_ai_go/pkg/common/ai"
	"yanxue_ai_go/pkg/common/config"
	"yanxue_ai_go/pkg/common/logger"
)

// AIService AI服务
type AIService struct {
	modelManager ai.ModelManager
	factory      *ai.ModelFactory
	config       *config.Config
}

// NewAIService 创建AI服务
func NewAIService(cfg *config.Config) (*AIService, error) {
	// 初始化模型管理器
	ai.InitializeModelManager()

	// 创建工厂
	factory := ai.NewModelFactory(cfg)

	// 从配置创建模型
	models, err := factory.CreateModelsFromConfig()
	if err != nil {
		return nil, fmt.Errorf("failed to create models from config: %w", err)
	}

	// 注册模型
	for _, model := range models {
		if err := ai.GlobalModelManager.RegisterModel(model); err != nil {
			logger.Logger.Error("Failed to register model",
				zap.String("model_id", model.GetModelInfo().ID),
				zap.Error(err))
		}
	}

	return &AIService{
		modelManager: ai.GlobalModelManager,
		factory:      factory,
		config:       cfg,
	}, nil
}

// Chat 对话
func (s *AIService) Chat(ctx context.Context, req ChatServiceRequest) (*ChatServiceResponse, error) {
	// 选择模型
	model, err := s.selectModel(req.ModelID, req.Provider, req.Criteria)
	if err != nil {
		return nil, fmt.Errorf("failed to select model: %w", err)
	}

	// 转换请求格式
	aiReq := ai.ChatRequest{
		Messages:         convertMessages(req.Messages),
		Model:            req.ModelID,
		Temperature:      req.Temperature,
		MaxTokens:        req.MaxTokens,
		TopP:             req.TopP,
		FrequencyPenalty: req.FrequencyPenalty,
		PresencePenalty:  req.PresencePenalty,
		Stop:             req.Stop,
		Stream:           req.Stream,
		Tools:            convertTools(req.Tools),
		ToolChoice:       req.ToolChoice,
		Metadata:         req.Metadata,
	}

	// 调用模型
	resp, err := model.Chat(ctx, aiReq)
	if err != nil {
		return nil, fmt.Errorf("model chat failed: %w", err)
	}

	// 转换响应格式
	return &ChatServiceResponse{
		ID:                resp.ID,
		Object:            resp.Object,
		Created:           resp.Created,
		Model:             resp.Model,
		Provider:          string(model.GetProvider()),
		Choices:           convertChoices(resp.Choices),
		Usage:             convertUsage(resp.Usage),
		SystemFingerprint: resp.SystemFingerprint,
	}, nil
}

// ChatStream 流式对话
func (s *AIService) ChatStream(ctx context.Context, req ChatServiceRequest) (<-chan ChatServiceResponse, error) {
	// 选择模型
	model, err := s.selectModel(req.ModelID, req.Provider, req.Criteria)
	if err != nil {
		return nil, fmt.Errorf("failed to select model: %w", err)
	}

	// 转换请求格式
	aiReq := ai.ChatRequest{
		Messages:    convertMessages(req.Messages),
		Model:       req.ModelID,
		Temperature: req.Temperature,
		MaxTokens:   req.MaxTokens,
		Stream:      true,
	}

	// 调用模型流式接口
	aiStream, err := model.ChatStream(ctx, aiReq)
	if err != nil {
		return nil, fmt.Errorf("model chat stream failed: %w", err)
	}

	// 转换流式响应
	responseChan := make(chan ChatServiceResponse, 10)
	go func() {
		defer close(responseChan)

		for aiResp := range aiStream {
			serviceResp := ChatServiceResponse{
				ID:       aiResp.ID,
				Object:   aiResp.Object,
				Created:  aiResp.Created,
				Model:    aiResp.Model,
				Provider: string(model.GetProvider()),
				Choices:  convertChoices(aiResp.Choices),
			}

			select {
			case responseChan <- serviceResp:
			case <-ctx.Done():
				return
			}
		}
	}()

	return responseChan, nil
}

// GetModels 获取可用模型列表
func (s *AIService) GetModels() ([]ModelServiceInfo, error) {
	models, err := s.modelManager.ListModels()
	if err != nil {
		return nil, err
	}

	var serviceModels []ModelServiceInfo
	for _, model := range models {
		serviceModels = append(serviceModels, ModelServiceInfo{
			ID:          model.ID,
			Provider:    string(model.Provider),
			Type:        string(model.Type),
			Name:        model.Name,
			Description: model.Description,
			MaxTokens:   model.MaxTokens,
			InputPrice:  model.InputPrice,
			OutputPrice: model.OutputPrice,
			Features:    model.Features,
		})
	}

	return serviceModels, nil
}

// SwitchModel 切换模型
func (s *AIService) SwitchModel(modelID string, config map[string]interface{}) error {
	model, err := s.modelManager.GetModel(modelID)
	if err != nil {
		return fmt.Errorf("model not found: %w", err)
	}

	if err := model.UpdateConfig(config); err != nil {
		return fmt.Errorf("failed to update model config: %w", err)
	}

	logger.Logger.Info("Model switched successfully",
		zap.String("model_id", modelID),
		zap.Any("config", config))

	return nil
}

// AddModel 动态添加模型
func (s *AIService) AddModel(provider ai.ModelProvider, modelName string, config map[string]interface{}) error {
	model, err := s.factory.CreateModel(provider, modelName, config)
	if err != nil {
		return fmt.Errorf("failed to create model: %w", err)
	}

	if err := s.modelManager.RegisterModel(model); err != nil {
		return fmt.Errorf("failed to register model: %w", err)
	}

	logger.Logger.Info("Model added successfully",
		zap.String("provider", string(provider)),
		zap.String("model_name", modelName))

	return nil
}

// RemoveModel 移除模型
func (s *AIService) RemoveModel(modelID string) error {
	if err := s.modelManager.UnregisterModel(modelID); err != nil {
		return fmt.Errorf("failed to unregister model: %w", err)
	}

	logger.Logger.Info("Model removed successfully", zap.String("model_id", modelID))
	return nil
}

// HealthCheck 健康检查
func (s *AIService) HealthCheck(ctx context.Context) (map[string]error, error) {
	return s.modelManager.HealthCheck(ctx)
}

// selectModel 选择模型
func (s *AIService) selectModel(modelID, provider string, criteria *ai.ModelSelectionCriteria) (ai.AIModel, error) {
	// 如果指定了模型ID，直接获取
	if modelID != "" {
		return s.modelManager.GetModel(modelID)
	}

	// 如果指定了提供商，从该提供商选择
	if provider != "" {
		models, err := s.modelManager.GetModelsByProvider(ai.ModelProvider(provider))
		if err != nil {
			return nil, err
		}
		if len(models) > 0 {
			return models[0], nil
		}
	}

	// 根据标准选择最佳模型
	if criteria != nil {
		return s.modelManager.GetBestModel(*criteria)
	}

	// 使用默认配置
	defaultProvider := ai.ModelProvider(s.config.AI.Default.Provider)
	defaultModel := s.config.AI.Default.Model

	return s.modelManager.GetModel(fmt.Sprintf("%s-%s", defaultProvider, defaultModel))
}

// 辅助转换函数
func convertMessages(messages []ChatServiceMessage) []ai.ChatMessage {
	aiMessages := make([]ai.ChatMessage, len(messages))
	for i, msg := range messages {
		aiMessages[i] = ai.ChatMessage{
			Role:    msg.Role,
			Content: msg.Content,
		}
	}
	return aiMessages
}

func convertTools(tools []ToolService) []ai.Tool {
	aiTools := make([]ai.Tool, len(tools))
	for i, tool := range tools {
		aiTools[i] = ai.Tool{
			Type: tool.Type,
			Function: ai.Function{
				Name:        tool.Function.Name,
				Description: tool.Function.Description,
				Parameters:  tool.Function.Parameters,
			},
		}
	}
	return aiTools
}

func convertChoices(choices []ai.Choice) []ChoiceService {
	serviceChoices := make([]ChoiceService, len(choices))
	for i, choice := range choices {
		serviceChoice := ChoiceService{
			Index: choice.Index,
			Message: ChatServiceMessage{
				Role:    choice.Message.Role,
				Content: choice.Message.Content,
			},
			FinishReason: choice.FinishReason,
		}

		if choice.Delta != nil {
			serviceChoice.Delta = &ChatServiceMessage{
				Role:    choice.Delta.Role,
				Content: choice.Delta.Content,
			}
		}

		serviceChoices[i] = serviceChoice
	}
	return serviceChoices
}

func convertUsage(usage ai.Usage) UsageService {
	return UsageService{
		PromptTokens:     usage.PromptTokens,
		CompletionTokens: usage.CompletionTokens,
		TotalTokens:      usage.TotalTokens,
	}
}
